/**
 * Class Range
 * @return
 */
function Range(first, last) {
	this.first = first;
	this.last = last;
}

/**
 * Class PaginationInterface
 * @param handler
 * @param rangeCount
 * @return
 */
function PaginationInterface(handler, rangeCount, itemsName, editable) {
	
	this.setCurrent = function(current) {
		var range = this.getRange(current);
		
		while (this.numbersSpan.hasChildNodes()) {
			this.numbersSpan.removeChild(this.numbersSpan.firstChild);
		}
		
		if (range.first > 0) {
			var leftContinue = document.createTextNode(" ... ");
			this.numbersSpan.appendChild(leftContinue);
		}
		
		for (var j=range.first ; j<=range.last ; j++) {
			this.numbersSpan.appendChild(this.numberButtons[j].tag);
			if (j == current) {
				this.numberButtons[j].tag.style.color = "#FFFFFF";
			} else {
				this.numberButtons[j].tag.style.color = "#777777";
			}
		}
		
		if (range.last < (this.numberButtons.length-1)) {
			var rightContinue = document.createTextNode(" ... ");
			this.numbersSpan.appendChild(rightContinue);
		}
	};
	
	this.addNumberButton = function(numberButton) {
		this.numberButtons[this.numberButtons.length] = numberButton;
		this.numbersSpan.appendChild(numberButton.tag);
	};
	
	this.getRange = function(current) {
		var pages = this.numberButtons.length;
		
		var first = current - (this.rangeCount-1)/2;
	    var last = current + (this.rangeCount-1)/2;
	    
	    if (first <= 0) {
	        var realFirst = 0;
	    }
	    
	    if (last >= (pages-1)) {
	        var realLast = (pages-1);
	    }
	    
	    if (realFirst != undefined) {
	        var suposedLast = realFirst + (this.rangeCount-1);
	        var realLast = (suposedLast > (pages-1)) ? (pages-1) : suposedLast;
	    } else if (realLast != undefined) {
	        var suposedFirst = ((realLast-(this.rangeCount-1)) < 0) ? 0 : (realLast-(this.rangeCount-1));
	        var realFirst = (suposedFirst < 0) ? 0 : suposedFirst;
	    } else {
	        var realFirst = first;
	        var realLast = last;
	    }
	    
	    var range = new Range(realFirst, realLast);
	    return range;
	};
	
	this.setElements = function(elements) {
		this.spanItemCount.innerHTML = elements;
	};
	
	this.getEditable = function() {
		return this.editable;
	};

	this.setEditable = function(editable) {
		this.editable = editable;
	};
 
	this.getHandler = function() {
		return this.handler;
	};

	this.setHandler = function(handler) {
		this.handler = handler;
	};

	this.getRangeCount = function() {
		return this.rangeCount;
	};

	this.setRangeCount = function(rangeCount) {
		this.rangeCount = rangeCount;
	};

	this.reset = function() {
		this.setElements(0);
		while (this.numbersSpan.hasChildNodes()) {
			this.numbersSpan.removeChild(this.numbersSpan.firstChild);
		}
		this.numberButtons.splice(0, this.numberButtons.length);
		var r = this.numberButtons.length;
	};

	// //////////////////////////////////////////////////////
	// View part
	this.tag = document.createElement("table");
	this.tag.width = "100%";
//	this.tag.border = 1;
	this.tbody = document.createElement("tbody");
	this.tag.appendChild(this.tbody);
	
	this.tr = document.createElement("tr");
	this.tbody.appendChild(this.tr);

	this.tdItemsName = document.createElement("td");
	this.tdItemsName.style.textAlign = "left";
	this.tdItemsName.width = "30%";
	this.tr.appendChild(this.tdItemsName);
	this.itemsName = document.createElement("span");
	this.tdItemsName.appendChild(this.itemsName);
	var _name = document.createTextNode(itemsName + ": [");
	this.itemsName.appendChild(_name);
	this.spanItemCount = document.createElement("span");
	this.itemsName.appendChild(this.spanItemCount);
	var name_ = document.createTextNode("]");
	this.itemsName.appendChild(name_);
	
	this.tdList = document.createElement("td");
	this.tdList.style.textAlign = "center";
	this.tdList.width = "40%";
	this.tr.appendChild(this.tdList);
	// //////////////////////////////////////////////////////

	// //////////////////////////////////////////////////////
	// Data part (attributes)
	this.handler = null;
	this.rangeCount = null;
	this.editable = null;
	//////////////////////////////////////////////////////

	// //////////////////////////////////////////////////////
	// Constructor body
	this.setEditable(editable);
	this.setHandler(handler);
	this.setRangeCount(rangeCount);
	this.setElements(0);
	// //////////////////////////////////////////////////////
	
	// //////////////////////////////////////////////////////
	// Buttons
	this.showPreviousButton = new ControlButton(this.handler, "showPrevious()", "img/go-previous.jpg", " Anterior ");
	this.tdList.appendChild(this.showPreviousButton.tag);
	
	this.numbersSpan = document.createElement("span");
	this.tdList.appendChild(this.numbersSpan);
	this.numberButtons = [];
	
	this.showNextButton = new ControlButton(this.handler, "showNext()", "img/go-next.jpg", " Siguiente ");
	this.tdList.appendChild(this.showNextButton.tag);
	
	this.tdAddButton = document.createElement("td");
	this.tdAddButton.style.textAlign = "right";
	this.tdAddButton.width = "30%";
	this.tr.appendChild(this.tdAddButton);
	
	if (editable) {
		this.addNewButton = new ControlButton(this.handler, "addNewElement()", "img/btn-anadir.gif", " Añadir ");
		this.tdAddButton.appendChild(this.addNewButton.tag);
	}
	// //////////////////////////////////////////////////////
}

/**
 * Class Pagination
 * @param handler
 * @param elemetsByPage
 * @param interfacesQty
 * @return
 */
function Pagination(elemetsByPage, interfacesQty, itemsName, editable) {
	
	this.addNewElement = function() {
		this.handler.addNewElement();
	};
	
	this.addElement = function() {
		var totalPages = this.getPages();
		var totalElements = this.getElements() + 1;
		
		this.setElements(totalElements);
		
		if (totalElements/totalPages > this.getElementsByPage()) {
			this.addPage();
		}
		
		for (var i=0 ; i<this.interfaces.length ; i++) {
			this.interfaces[i].setElements(this.getElements());
		}
	};
	
	this.addPage = function() {
		var pageNumber = this.getPages();
		this.setPages(pageNumber + 1);
		
		for (var i=0 ; i<this.interfaces.length ; i++) {
			var labelButton = new LabelButton(this, "showPage(" + pageNumber + ")", " " + this.getPages() + " ");
			this.interfaces[i].addNumberButton(labelButton);
		}
		
	};
	
	this.last = function() {
		return this.getPages() - 1;
	};
	
	this.next = function() {
		var last = this.last();
		var next = this.getCurrent() + 1;
		return (next > last) ? last : next;
	};
	
	this.previous = function() {
		var first = 0;
		var next = this.getCurrent() - 1;
		return (next < first) ? first : next;
	};
	
	this.init = function(number) {
		return this.elemetsByPage * number;
	};
	
	this.end = function(number) {
		var init = this.init(number);
		var elements = this.elements;
		var end = init + elemetsByPage;
		return end > elements ? elements : end;
	};
	
	this.getElements = function() {
		return this.elements;
	};
	
	this.setElements = function(elements) {
		this.elements = elements;
	};
	
	this.getPages = function() {
		return this.pages;
	};
	
	this.setPages = function(pages) {
		this.pages = pages;
	};
	
	this.getCurrent = function() {
		return this.current;
	};
	
	this.setCurrent = function(current) {
		this.current = current;
		for (var i=0 ; i<this.interfaces.length ; i++) {
			this.interfaces[i].setCurrent(current);
		}
	};
	
	this.getElementsByPage = function() {
		return this.elemetsByPage;
	};
	
	this.setElemetsByPage = function(elemetsByPage) {
		this.elemetsByPage = elemetsByPage;
	};
	
	this.showPage = function(number) {

		var init = this.init(number);
		var end = this.end(number);

		var range = new Range(init, end);

		this.handler.showRange(range);
		
		this.setCurrent(number);
	};
	
	this.showNext = function() {
		var next = this.next();
		this.showPage(next);
	};
	
	this.showPrevious = function() {
		var previous = this.previous();
		this.showPage(previous);
	};
	
	this.showLast = function() {
		var last = this.last();
		this.showPage(last);
	};
	
	this.showFirst = function() {
		this.showPage(0);
	};
	
	this.getInterface = function(index) {
		return this.interfaces[index];
	};
	
	this.showElementPage = function(index) {
		var number = 0;
		var elements = this.getElementsByPage();
		if(index > this.last()) {
			number = this.last();
		} else if(index < 0) {
			number = 0;
		} else {
			number = Math.floor(index/elements);
		}
		
		this.showPage(number);
	};
	
	this.getHandler = function() {
		return this.handler;
	};

	this.setHandler = function(handler) {
		this.handler = handler;
	};

	this.reset = function() {
		this.elements = 0;
		this.pages = 0;
		this.setCurrent(0);

		for (var i=0 ;i<this.interfaces.length ; i++) {
			this.interfaces[i].reset();
		}

		this.addPage();
	};

	this.handler = null;

	this.elements = 0;
	this.pages = 0;
	this.elemetsByPage = elemetsByPage;
	this.current = -1;
	
	this.interfaces = [];
	for (var i=0 ;i<interfacesQty ; i++) {
		this.interfaces[i] = new PaginationInterface(this, 5, itemsName, editable);
	}
	
	this.addPage();
}
